﻿// <copyright file="Direction.cs" company="Ecole Normale Supérieure">
// Released under GPLv2
// </copyright>
// <summary>Direction enumeration.</summary>

namespace Sqwarea.Persistence
{
    using System;
    using System.Collections;
    using System.Collections.Generic;

    /// <summary>
    /// This is an wrapper for direction, starting from north, clockwise direction.
    /// </summary>
    public enum Direction
    {
        /// <summary>
        /// Direction North: (0, -1)
        /// </summary>
        North,

        /// <summary>
        /// Direction East: (1, 0)
        /// </summary>
        East,

        /// <summary>
        /// Direction South: (0, 1)
        /// </summary>
        South,

        /// <summary>
        /// Direction West: (-1, 0)
        /// </summary>
        West
    }

    /// <summary>
    /// An enumerator provided by IConnexityBuffer to ConnexityProvider
    /// </summary>
    public class Directions : IEnumerable<Direction>
    {
        /// <summary>
        /// Returns the opposite direction.
        /// </summary>
        /// <param name="dir">A direction.</param>
        /// <returns>The opposite direction</returns>
        public static Direction Opposite(Direction dir)
        {
            switch (dir)
            {
                case Direction.North:
                    {
                        return Direction.South;
                    }

                case Direction.South:
                    {
                        return Direction.North;
                    }

                case Direction.East:
                    {
                        return Direction.West;
                    }

                case Direction.West:
                    {
                        return Direction.East;
                    }

                default:
                    throw new ArgumentOutOfRangeException("dir", "Opposite function");
            }
        }

        /// <summary>
        /// An enumerator used to get access to the "foreach" syntax 
        /// on directions.
        /// </summary>
        /// <returns>Yields each a time a new direction.</returns>
        public IEnumerator<Direction> GetEnumerator()
        {
            yield return Direction.North;
            yield return Direction.East;
            yield return Direction.South;
            yield return Direction.West;
        }

        /// <summary>
        /// An alias for the other GetEnumerator(), 
        /// to properly implement the IEnumerable interface.
        /// </summary>
        /// <returns>Yields each a time a new direction.</returns>
        IEnumerator IEnumerable.GetEnumerator()
        {
            yield return GetEnumerator();
        }
    }
}